﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Pavilion
{
    public class AnimationCollection : IResourceCollection, IEnumerable<Animation>
    {
        public event Action<Animation> AnimationAdded, AnimationRemoved;

        public Animation this[string animationName] { get { return animationDictionary[animationName]; } }
        public IEnumerable<Animation> AnimationList { get { return animationDictionary.Values; } }

        private Dictionary<string, Animation> animationDictionary = new Dictionary<string,Animation>();

        public void Dispose()
        {
            while (animationDictionary.Count != 0)
                animationDictionary.Values.First().Dispose();

            animationDictionary = null;
        }

        static public AnimationCollection LoadFromDirectory(string resourcePath)
        {
            string buildPath = resourcePath + @"Built Data\";
            IEnumerable<Animation> animationList = new AnimationXmlSerializer().DeserializeCollection(resourcePath + "AnimationList.xml");

            foreach (Animation animation in animationList)
            {
                for (int i = 0; i < animation.FrameList.Count; i++)
                {
                    animation.FrameList[i].CreateTexturesFromFolder(buildPath + animation.Name + @"\" + i);
                    animation.LoadAllFrames(buildPath);
                }
            }

            AnimationCollection animationCollection = new AnimationCollection();
            animationCollection.AddAnimationList(animationList);

            return animationCollection;
        }

        public void AddAnimationList(IEnumerable<Animation> animationList)
        {
            foreach (Animation animation in animationList)
                AddAnimation(animation);
        }

        public void AddAnimation(Animation animation)
        {
            animationDictionary.Add(animation.Name, animation);

            animation.NameChanged += new NameChangedDelegate(Animation_NameChanged);
            animation.Disposed += (disposedAnimation) => { animationDictionary.Remove(disposedAnimation.Name); OnAnimationRemoved(disposedAnimation); };
            //animation.LoadAllFrames(BuiltDataPath);

            OnAnimationAdded(animation);
        }

        public void RemoveAnimation(string animationName)
        {
            this[animationName].Dispose();
        }

        public Animation AddNewAnimation()
        {
            Animation animation = new Animation() { Name = GameEngine.GetUniqueName(animationDictionary.Keys, "Animation") };
            AddAnimation(animation);

            return animation;
        }

        public bool Contains(string animationName)
        {
            return animationDictionary.ContainsKey(animationName);
        }

        private void OnAnimationAdded(Animation animation)
        {
            if (AnimationAdded != null)
                AnimationAdded(animation);
        }

        private void OnAnimationRemoved(Animation animation)
        {
            if (AnimationRemoved != null)
                AnimationRemoved(animation);
        }

        private void Animation_NameChanged(string oldName, string newName)
        {
            Animation animationToUpdate = animationDictionary[oldName];
            animationDictionary.Remove(oldName);
            animationDictionary.Add(newName, animationToUpdate);
        }

        public IEnumerator<Animation> GetEnumerator() { return animationDictionary.Values.GetEnumerator(); }
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return animationDictionary.Values.GetEnumerator(); }
    }
}
